{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Fuzzy K-Means 算法步骤"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. 若有$M$个样本，指定类别数为$C$，初始化隶属度矩阵$\\boldsymbol U(0)_{C\\times M}$，选取加权指数$m$，一般选在1.5~2.5\n",
    "2. 根据式子$\\boldsymbol c_i=\\frac{\\sum_{j=1}^Mu_{ij}^m\\boldsymbol x_j}{\\sum_{j=1}^Mu_{ij}^m}$计算或更新聚类中心。\n",
    "3. 根据式子$u_{ij}=\\frac{1}{\\sum_{i=1}^C(\\frac{\\boldsymbol x_j-\\boldsymbol c_k}{\\boldsymbol x_j-\\boldsymbol c_i})^{\\frac{2}{m-1}}}$更新隶属度矩阵\n",
    "4. 如果满足终止条件$\\max_{ij}{||u(t+1)_{ij}-u(t)_{ij}||}\\le \\varepsilon$，则停止迭代。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "数据集：shape (150, 2)\n",
      "隶属度矩阵初始化完成：shape= (3, 150)\n",
      "满足条件，返回新的聚类中心和新的隶属度矩阵\n",
      "分为第0类的样本索引值为\n",
      "(array([ 50,  51,  52,  54,  56,  58,  65,  74,  75,  76,  77,  86, 100,\n",
      "       102, 103, 104, 105, 107, 108, 109, 110, 111, 112, 115, 116, 117,\n",
      "       118, 120, 122, 123, 124, 125, 128, 129, 130, 131, 132, 133, 135,\n",
      "       136, 137, 139, 140, 141, 143, 144, 145, 147, 148], dtype=int64),)\n",
      "分为第1类的样本索引值为\n",
      "(array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,\n",
      "       17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,\n",
      "       34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49],\n",
      "      dtype=int64),)\n",
      "分为第2类的样本索引值为\n",
      "(array([ 53,  55,  57,  59,  60,  61,  62,  63,  64,  66,  67,  68,  69,\n",
      "        70,  71,  72,  73,  78,  79,  80,  81,  82,  83,  84,  85,  87,\n",
      "        88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99, 101,\n",
      "       106, 113, 114, 119, 121, 126, 127, 134, 138, 142, 146, 149],\n",
      "      dtype=int64),)\n"
     ]
    },
    {
     "data": {
      "text/plain": "<Figure size 864x576 with 1 Axes>",
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAsIAAAHSCAYAAADmLK3fAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAAAsTAAALEwEAmpwYAABfnUlEQVR4nO3deXhU1f3H8feZfZKQsO8IKLIp4oKC4r4vuK/VWqW11l3b2tZu2tr6s1XrVqutWq37hlrRuu87Au6KIrLvAQIhyexzfn9MhCwTuAmTmUzu5/U8PJBzJt9853KTfObOufcaay0iIiIiIm7jKXQDIiIiIiKFoCAsIiIiIq6kICwiIiIirqQgLCIiIiKupCAsIiIiIq6kICwiIiIiruRz+kBjjBeYASyx1k5qMncmcC2wpH7oFmvtnZuq17NnTztkyJBWNSsiIiIi0lozZ85cZa3t1XTccRAGLgZmAeUtzD9irb3AabEhQ4YwY8aMVnx5EREREZHWM8YsyDbuaGmEMWYgcASwyaO8IiIiIiLFwuka4RuBXwLpTTzmeGPMp8aYKcaYQdkeYIw52xgzwxgzo7KyspWtioiIiIjkzmaDsDFmErDSWjtzEw97Ghhird0BeAm4J9uDrLW3W2vHWWvH9erVbJmGiIiIiEjeODkiPBE4yhgzH3gY2N8Yc3/DB1hrV1trY/Uf3gnsktMuRURERERybLNB2Fr7a2vtQGvtEOAU4FVr7fcbPsYY06/Bh0eROalORERERKTDas1VIxoxxlwJzLDWTgUuMsYcBSSBNcCZuWlPRERERKR9GGttQb7wuHHjrC6fJiIiIiLtzRgz01o7rum47iwnIiIiIq6kICwiIiIirqQgLCIiIiKupCAsIiIiIq6kICwiIiIirqQgLCIiIiKupCAsIiIiIq7U5htqiIi0p3cXLeS2GdNYVF3Nrv37c8GuuzO4a9dCtyUiIp2IgrCIdDj//epLfvPqS0STSQAWV6/jhW/n8N+TT2Prbt0L3J2IiHQWWhohIh1KKp3myjdf2xCCAdLWUpdIcOP77xawMxER6WwUhEWkQ1leU9MoBH8nbS0fLFlcgI5ERKSzUhAWkQ6lPBgkbW3Wud6lpXnuRkREOjMFYRHpULoEgxw2bDhBr7fReNjn45xxuxWoKxER6Yx0spyIdDhXH3AQyXSKl+Z+i9/jJW0tl4zfncO3HVHo1kREpBNREBaRDifk8/P3w45kTaSOyro6BldUEPL5C92WiIh0MgrCItJhdQ+X0D1cUug2RESkk9IaYRERERFxJQVhEREREXElBWERERERcSUFYRERERFxJQVhEREREXElBWERERERcSUFYRERERFxJQVhEREREXElBWERERERcSUFYRERERFxJQVhEREREXElBWERERERcSUFYRERERFxJQVhEREREXElBWERERERcSUFYRERERFxJQVhEREREXElBWERERERcSUFYRERERFxJQVhEREREXElBWERERERcSUFYRERERFxJQVhEREREXElBWERERERcSVfoRsQkY7lk+XL+Nv77/DVqkqGdu3GxeP3YI9BWxW6LRERkZzTEWER2WD60sV874lHeXvhAlbV1TF96RLOevpJXvz2m0K3JiIiknMKwiKywf+99QbRZLLRWDSZ5E9vvl6YhkRERNqRgrCIbPDVqsqs48tq1hNrEpBFRESKnYKwiGzQs6Q063iJz0/A681zNyIiIu1LQVhENjhv1/GEfY3PoQ37fPxop10wxhSoKxERkfahq0aIyAanbDeG6miUW6a/T9paAH4wdicuHL97gTsTERHJPQVhEdnAGMNPxu3G5J12obK2lh4lYUI+f6HbEhERaRcKwiLSTMDrZUB5eaHbEBERaVdaIywiIiIirqQgLCIiIiKupCAsIiIiIq6kICwiIiIirqQgLCIiIiKupCAsIiIiIq6kICwiIiIirqTrCIvkyNL11by3eBFdAgH2GTyUoE/fXiIiIh2ZflOL5MD1773DHR9Ox+vx4DEGjzHcc8wJjO3Tt9CtiYiISAu0NEJkC72zaAH//mgGsVSKukSCmnic6liMH019gmQ6Xej2REREpAUKwiJb6OHPPyOSTDYbjydTzFi6pAAdiYiIiBMKwiJbKJJIZJ8wEM0SkEVERKRjUBAW2UKTho8k7PM3G0+m0+zaf0ABOhIREREnFIRFttCk4SPYuV8/SvyZMOw1hpDPx1X7H0RpIFDg7kRERKQlumqEyBbyeTz85+jjeW3+XF6a+y1dQyFOGr0923TvUejWREREZBMUhEVywOvxcODWwzhw62GFbkVEREQc0tIIEREREXElBWERERERcSUFYRERERFxJQVhEREREXElBWERERERcSUFYRERERFxJQVhEREREXEl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9neIZPM+ffMLrp18KysWVOIP+jj0hwdw/k2T8bTi6jsLvlzEf37/CLOmzabXwB6c9rsTmDBpl3bsuv289/QMHrzqcSoXr2bUhOGceeXJDB7t/PeKtZbXHn6HR699irUr17Hj/mM4448n0W9oH8c10uk0z97xCv/9+7PUrqtj96PG8f3fn0D3vvl9lzBaF+PRa5/ipXvfAOCgH+zDSb84ulFIF2mrlk6WUxAWERERkU5NV40QEREREWlAQVhEREREXElBWERERERcSUFYRERERFxJQVhEREREXElBWERERERcSUFYRERERFxJQVhEREREXKn5jc6lw5u/top7P/mYBeuqmDBgECdvP4byYCjvfXyyfBkPfPYJa6NRDhm2LUcOH0nA27pbnN710Uzu/vhDEqkUk4aP4Jd77EXAp91SpLOK1sV48T+v88HzH9FrQHeOOu8Qho4pzluiv/fMTG4651+sq6ymx4DuXHbfRWw/cWTe+5hyw9M88KcpROviDNl+EH944hf02Up3PxRxQneWKzLvLVrIWU8/SSKVImktIZ+PimCQqd87nV4lpXnr495PPuIv77xJPJUibS1hn58RPXry0PEnEXQYZE987CFmLlvaaKx7OMz7PzoHXytutyoixaG2uo4Lxv+aykWridXF8Hg9+IM+fnH3Bexz4u6Fbq9VHrr6Ce767UPNxn917wUc+P198tbHbyf9Hx88+1Gz8Tu/uIHBowbmrQ+Rjk53lusErLX84uXniSSTJOtfwESTSVZHItw87b289VEdi3L1228STSZJ1/cRSSb4evUqps7+ylGNmUuXNAvBAGsiEW6dPi2n/YpIx/DULc+xckElsboYAOlUmlhdnBvO/ieJeKLA3bXO3b9/OOv49Wf9M289rFuzPmsIBvj9kX/JWx8ixUxBuIgsq1nP6rpIs/FkOs3Lc7/NWx8zli7F722+60SSCZ6bM9tRjYe/+KzFuacdhmkRKS5vTnmfeLR54LVpy9xPFxago7ZZt2Y9Np393dREPJm3Pp76+3Mtzi2ftzJvfYgUMwXhIlLi9284AttUWSCQtz7KAgGyLakxQFeHa5UrgsEW58oDLc+JSPEqrSjJOp5KpSgtD+e5m7YLhPP383ZTeg3s0eKc8Zo8diJSvBSEi0jXUJjdBgxotn427PPxg7E75a2PXfr1pzRL8A75fJw6Zqyj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I9HSCBERERFxJQVhEREREXElBWERERERcSUFYRERERFxJQVhEREREXElBWERERERcSUFYRERERFxJQVhEREREXElBWERERERcSUFYRERERFxJQVhEREREXElBWERERERcSUFYRERERFxJQVhEREREXElBWERERERcSUFYRERERFxJQVhEREREXElBWERERERcSUFYRERERFxJQVhEREREXElBWERERERcSUFYRERERFxJQVhEREREXElBWERERERcSVfoRsQ2VI2tQyiL2c+CB2I8fYrbEMiIiJSFDZ7RNgYM8gY85ox5ktjzBfGmIuzPMYYY242xswxxnxqjNm5fdoVaSxd+wC28mDs+msyfyoPJl37QKHbEhERkSLgZGlEEvi5tXY0MAE43xgzusljDgO2rf9zNnBbTrsUycImF8P6vwCxxn/W/yUzJyIiIrIJmw3C1tpl1toP6/+9HpgFDGjysKOBe23G+0BXY4zen5b2FXsBsFkmbP2ciIiISMtadbKcMWYIsBMwrcnUAGBRg48X0zwsY4w52xgzwxgzo7KyspWtijRh07QYhG06392IiIhIkXEchI0xZcDjwCXW2uq2fDFr7e3W2nHW2nG9evVqSwmRjUIHkn0X9kDooHx3IyIiIkXGURA2xvjJhOAHrLVPZHnIEmBQg48H1o+JtBvjGwpl5wFBwFv/Jwhl52N8Qwram4iIiHR8m718mjHGAP8GZllrr2/hYVOBC4wxDwPjgXXW2mW5a1MkO0/ZudjQQdjI8wCY8KEY37ACdyUiIiLFwMl1hCcCpwOfGWM+rh/7DbAVgLX2n8CzwOHAHKAOmJzzTkVaYHzDMF0uKHQbIiIiUmQ2G4SttW8DZjOPscD5uWpKRERERKS96RbLIiIiIuJKCsIiIiIi4koKwiIiIiLiSgrCIiIiIuJKCsIiIiIi4koKwiIiIiLiSgrCIiIiIuJKCsIiIiIi4koKwiIiIiLiSgrCIiIiIuJKCsIiIiIi4koKwiIiIiLiSgrCIiIiIuJKCsIiIiIi4krGWluYL2xMJbCgIF+8Y+gJrCp0E52MtmnuaZvmlrZn7mmb5pa2Z+5pm+ZWW7fnYGttr6aDBQvCbmeMmWGtHVfoPjoTbdPc0zbNLW3P3NM2zS1tz9zTNs2tXG9PLY0QEREREVdSEBYRERERV1IQLpzbC91AJ6Rtmnvaprml7Zl72qa5pe2Ze9qmuZXT7ak1wiIiIiLiSjoiLCIiIiKupCAsIiIiIq6kIJwHxhivMeYjY8wzWebONMZUGmM+rv9zViF6LCbGmPnGmM/qt9eMLPPGGHOzMWaOMeZTY8zOheizWDjYnvsaY9Y12EcvL0SfxcQY09UYM8UY85UxZpYxZvcm89pHW8HB9tQ+2grGmBENttXHxphqY8wlTR6jfbQVHG5T7aetYIz5qTHmC2PM58aYh4wxoSbzQWPMI/X76DRjzJC2fB1fTrqVzbkYmAWUtzD/iLX2gjz20xnsZ61t6YLahwHb1v8ZD9xW/7e0bFPbE+Ata+2kvHVT/G4CnrfWnmCMCQAlTea1j7bO5rYnaB91zFr7NbAjZA7UAEuAJ5s8TPtoKzjcpqD91BFjzADgImC0tTZijHkUOAX4T4OH/QiostYOM8acAvwVOLm1X0tHhNuZMWYgcARwZ6F7cZGjgXttxvtAV2NMv0I3Je5gjKkA9gb+DWCtjVtr1zZ5mPZRhxxuT2m7A4BvrbVN7/SqfbTtWtqm0jo+IGyM8ZF58bu0yfzRwD31/54CHGCMMa39IgrC7e9G4JdAehOPOb7+racpxphB+WmrqFngRWPMTGPM2VnmBwCLGny8uH5Mstvc9gTY3RjziTHmOWPMdvlsrggNBSqBu+uXRN1pjClt8hjto8452Z6gfbStTgEeyjKufbTtWtqmoP3UEWvtEuA6YCGwDFhnrX2xycM27KPW2iSwDujR2q+lINyOjDGTgJXW2pmbeNjTwBBr7Q7AS2x8dSMt29NauzOZt+7ON8bsXeiGitzmtueHZO7RPhb4O/DfPPdXbHzAzsBt1tqdgFrgssK2VNScbE/to21Qv8zkKOCxQvfSWWxmm2o/dcgY043MEd+hQH+g1Bjz/fb4WgrC7WsicJQxZj7wMLC/Meb+hg+w1q621sbqP7wT2CW/LRaf+leKWGtXklmDtVuThywBGh5ZH1g/Jllsbntaa6uttTX1/34W8Btjeua90eKxGFhsrZ1W//EUMkGuIe2jzm12e2ofbbPDgA+ttSuyzGkfbZsWt6n201Y5EJhnra201iaAJ4A9mjxmwz5av3yiAljd2i+kINyOrLW/ttYOtNYOIfNWyavW2kavaJqsuTqKzEl10gJjTKkxpst3/wYOBj5v8rCpwA/qz3qeQOYtlWV5brUoONmexpi+3627MsbsRubnRqt/2LiFtXY5sMgYM6J+6ADgyyYP0z7qkJPtqX20zb5Hy2/hax9tmxa3qfbTVlkITDDGlNRvswNono+mAmfU//sEMhmr1XeJ01UjCsAYcyUww1o7FbjIGHMUkATWAGcWsrci0Ad4sv5niQ940Fr7vDHmHABr7T+BZ4HDgTlAHTC5QL0WAyfb8wTgXGNMEogAp7Tlh43LXAg8UP826VxgsvbRLbK57al9tJXqX/geBPykwZj20S3gYJtqP3XIWjvNGDOFzHKSJPARcHuT/PRv4D5jzBwy+emUtnwt3WJZRERERFxJSyNERERExJUUhEVERETElRSERURERMSVFIRFRERExJUUhEVERETElRSERURERMSVFIRFRERExJX+Hyqf9562u9iaAAAAAElFTkSuQmCC\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import numpy as np\n",
    "from copy import deepcopy\n",
    "from sklearn.datasets import load_iris\n",
    "import matplotlib.pyplot as plt\n",
    "np.random.seed(0)\n",
    "# 初始化隶属度矩阵 U，列和为1\n",
    "def init_fuzzy_matrix(C, n_sample):\n",
    "    \"\"\"\n",
    "    param n_sample: 样本数量\n",
    "    param C: 聚类数量\n",
    "    \"\"\"\n",
    "    fuzzy_matrix = np.random.randint(1,10,size=(C,n_sample))  \n",
    "    \n",
    "    column_sum=np.sum(fuzzy_matrix,axis=0)\n",
    "    # 使得每列之和为1\n",
    "    fuzzy_matrix=fuzzy_matrix/column_sum\n",
    "\n",
    "    return fuzzy_matrix\n",
    "\n",
    "# 计算聚类中心\n",
    "def cluster_centers(X,fuzzy_matrix,m):\n",
    "    \"\"\"\n",
    "    param X: 数据集的特征集\n",
    "    param fuzzy_matrix: 隶属度矩阵\n",
    "    param m: 加权指数\n",
    "    \"\"\"\n",
    "    molecular=np.dot(fuzzy_matrix**m,X)\n",
    "    denominator=np.sum(fuzzy_matrix**m,axis=1)\n",
    "    c=molecular/(denominator.reshape(-1,1))\n",
    "\n",
    "    return c\n",
    "\n",
    "# 更新隶属度矩阵\n",
    "def update_fuzzy_matrix(X,c,m=2):\n",
    "    \"\"\"\n",
    "    param X: 数据集的特征集\n",
    "    param c:聚类中心矩阵\n",
    "    param m: 加权指数\n",
    "    \"\"\"\n",
    "    # 指数\n",
    "    exponential = 1.0/(m-1)\n",
    "    C,_=c.shape\n",
    "    n_sample,_=X.shape\n",
    "\n",
    "    # 两个与隶属度矩阵一样大小的临时矩阵\n",
    "    temp_matrix=np.ones((C,n_sample))\n",
    "    fuzzy_matrix=np.ones_like(temp_matrix)\n",
    "\n",
    "    # 遍历样本\n",
    "    for i,x in enumerate(X):\n",
    "        single_matrix=np.sum((c-x)**2,axis=1)\n",
    "        temp_matrix[:,i]=single_matrix.reshape(-1,1).ravel()\n",
    "\n",
    "    for row in range(C):\n",
    "        for column in range(n_sample):\n",
    "            fuzzy_matrix[row,column]=1.0/np.sum(temp_matrix[row,column]/temp_matrix[:,column])\n",
    "\n",
    "    return fuzzy_matrix**exponential\n",
    "\n",
    "# 训练\n",
    "def fuzzy_k_means(X,C,epsilon=0.1,m=2):\n",
    "    \"\"\"\n",
    "    param X: 数据集的特征集\n",
    "    param C:聚类中心数量\n",
    "    param epsilon: 训练终止条件\n",
    "    param iter_num: 迭代次数设定\n",
    "    param m: 加权指数\n",
    "    \"\"\"\n",
    "    n_sample,_=X.shape\n",
    "\n",
    "     # 初始化隶属度矩阵\n",
    "    fuzzy_matrix=init_fuzzy_matrix(n_sample=n_sample,C=C)\n",
    "    print(\"隶属度矩阵初始化完成：shape=\",fuzzy_matrix.shape)\n",
    "\n",
    "    while True:\n",
    "        # 先记录一下隶属度矩阵，用于判定终止条件，需要深拷贝\n",
    "        remember_fuzzy_matrix=deepcopy(fuzzy_matrix)\n",
    "        # 计算聚类中心\n",
    "        c=cluster_centers(X=X,fuzzy_matrix=fuzzy_matrix,m=m)\n",
    "        # 更新隶属度矩阵\n",
    "        fuzzy_matrix=update_fuzzy_matrix(X=X,c=c,m=m)\n",
    "        # 判断终止条件\n",
    "        if np.max(fuzzy_matrix-remember_fuzzy_matrix)<epsilon:\n",
    "            print(\"满足条件，返回新的聚类中心和新的隶属度矩阵\")\n",
    "            return (c,fuzzy_matrix)\n",
    "\n",
    "\n",
    "X,y=load_iris(return_X_y=True)\n",
    "\n",
    "# 只取两个特征，便于可视化\n",
    "X=X[:,:2]\n",
    "print(\"数据集：shape\",X.shape)\n",
    "# 分类数\n",
    "C=3\n",
    "# 获取训练结果\n",
    "c,fuzzy_matrix=fuzzy_k_means(X=X,C=C,epsilon=0.1,m=2)\n",
    "\n",
    "# 根据隶属度矩阵，将每列的最大值设为1，其余设为0\n",
    "classification_matrix=(fuzzy_matrix == fuzzy_matrix.max(axis=0, keepdims=0)).astype(float)\n",
    "\n",
    "y_lable=deepcopy(y)\n",
    "\n",
    "# 根据判定结果划分类，确定每行中元素为1的索引号，在y_label中进行标签的更改\n",
    "for row in range(C):\n",
    "    print(f\"分为第{row}类的样本索引值为\")\n",
    "    class_index=np.where(classification_matrix[row]==1)\n",
    "    print(class_index)\n",
    "    for index in class_index:\n",
    "        y_lable[index]=row\n",
    "\n",
    "# 可视化\n",
    "fig=plt.figure(figsize=(12,8))\n",
    "plt.scatter(X[:,0],X[:,1],c=y_lable)\n",
    "plt.scatter(c[:,0],c[:,1],marker='x')\n",
    "plt.show()\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}